package MusicLandscape.util;

import java.util.Objects;

/**
 * This class represents the concept of matching an object by some integer within a lower and upper bound.
 * <p>
 * More precisely, a valid pattern is a String that can be interpreted as either a single integer number
 * (leading and trailing whitespace are ignored, if present) which then represents the lower bound
 * or two integer numbers, separated by (any number of) whitespace, which then represent lower and upper bound.
 * <p>
 * The bounds are understood to be inclusive.
 *
 * @author Jonas Altrock (ew20b126@technikum-wien.at)
 * @version 1
 * @since LabWork
 */
abstract public class MyRangeMatcher<T> extends MyMatcher<T> implements ConsoleScanable {
    /**
     * the lower bound of the accepted range.
     */
    protected int lower;
    /**
     * the upper bound of the accepted range.
     */
    protected int upper;

    /**
     * The prompt displayed for changing this matcher's pattern.
     */
    protected String prompt = "enter range";

    /**
     * Creates a Matcher object with a specified pattern.
     *
     * @param pat the pattern of this matcher
     */
    public MyRangeMatcher(String pat) {
        super(pat);
    }

    /**
     * Sets the pattern of this matcher.
     * <p>
     * Interprets the argument as described in the class documentation. First sets the lower, then the upper bound.
     * The bounds specified are set if and only if at the time of setting they are actually lower (for the lower bound)
     * or higher (for the upper bound) than the other or at least equal to the other.
     *
     * @param pat the pattern to set
     */
    @Override
    public void setPattern(String pat) {
        String[] parts = pat.trim().split("\\s+");

        lower = 0;
        upper = Integer.MAX_VALUE;

        if (parts.length < 1 || parts[0].isEmpty()) {
            return;
        }

        try {
            lower = Integer.max(Integer.parseInt(parts[0]), 0);
        } catch (NumberFormatException ignored) {}

        if (parts.length < 2) {
            return;
        }

        try {
            int upperBound = Integer.min(Integer.parseInt(parts[1]), upper);

            if (upperBound >= lower) {
                upper = upperBound;
            }
        } catch (NumberFormatException ignored) {}
    }

    /**
     * the valid pattern is <kbd>LOWER UPPER</kbd> separated by whitespace.
     *
     * @return the pattern
     */
    @Override
    public String getPattern() {
        return lower + " " + upper;
    }

    /**
     * Interactively modify this matcher.
     *
     * @return whether this object was altered or not
     */
    @Override
    public boolean scan() {
        String pattern = ConsoleScanner.nonEmptyString.scan(prompt);

        if (pattern != null) {
            String before = getPattern();
            setPattern(pattern);
            return !Objects.equals(before, getPattern());
        }

        return false;
    }
}
